import random
from common.common_operation import CommonOperation
from common.read_xmind import ReadXmind
from common.test_data import TestData
import copy

test_data = TestData()


class InputOperation(CommonOperation):

    @staticmethod
    def data_len_limit(need_data):
        """判断是否有字符长度限制"""
        if '字符长度' in need_data.keys():
            if len(need_data['字符长度']['value']) > 1:
                return random.randint(int(need_data['字符长度']['value'][0]), int(need_data['字符长度']['value'][1]))
            return int(need_data['字符长度']['value'][0])
        return 10

    @staticmethod
    def data_type_limit(need_data):
        """判断是否有数据类型限制"""
        if '可以有的数据类型' in need_data.keys():
            if '必须有的数据类型' in need_data.keys():
                return need_data['必须有的数据类型']['value'].split(',')
            return need_data['可以有的数据类型']['value'].split(',')[0]
        if '必须有的数据类型' in need_data.keys():
            return need_data['必须有的数据类型']['value'].split(',')
        return '字母'

    def data_type_case(self, key, model_data, data_type, data_step, need_data, result1, result2, case_data):
        """根据类型生成用例"""
        for i in data_type:
            get_data = test_data.test_data(i, self.data_len_limit(need_data))
            if len(data_type) > 1:
                case_title = "{},{}：只包含{}一种数据类型，{}".format(model_data['用例标题'], data_step, i,
                                                           self.case_tip(model_data, need_data[key], result1))
                self.step_common(model_data, data_step, get_data, result1, case_data, case_title)
            else:
                case_title = "{},{}：只包含{}一种数据类型，{}".format(model_data['用例标题'], data_step, i,
                                                           self.case_tip(model_data, need_data[key], result2))
                self.step_common(model_data, data_step, get_data, result2, case_data, case_title)
        if len(data_type) > 1:
            # TODO 包含所有必填
            case_title = "{},{}：包含{}多种数据类型，{}".format(model_data['用例标题'], data_step, data_type,
                                                      self.case_tip(model_data, need_data[key], result2))
            get_data = test_data.test_data(data_type, self.data_len_limit(need_data))
            self.step_common(model_data, data_step, get_data, result2, case_data, case_title)

    def data_len_case(self, model_data, need_data, data_step, data_len, title, result, case_data):
        """根据长度生成用例"""
        if title == '小于':
            test_step_data = int(data_len) - 1
        elif title == '大于':
            test_step_data = int(data_len) + 1
        else:
            test_step_data = int(data_len)
        case_title = "{},{}：字符长度{}{}，{}".format(model_data['用例标题'], data_step, title, data_len,
                                                self.case_tip(model_data, need_data['字符长度'], result))
        get_data = test_data.test_data(self.data_type_limit(need_data), test_step_data)
        self.step_common(model_data, data_step, get_data, result, case_data, case_title)

    def data_type_special(self, model_data, need_data, data_step, keyword, case_data):
        """
        生成特殊类型相关用例
        :param model_data:
        :param need_data:
        :param data_step:
        :param keyword:
        :param case_data:
        :return:
        """
        tip = self.case_tip(model_data, need_data['特殊类型'], result)
        if keyword.upper() == 'IPV4':
            case_title = "{},{}：符合IPV4格式的数据，{}".format(model_data['用例标题'], data_step, tip)
            self.step_common(model_data, data_step, test_data.test_data('ipv4'), '成功', case_data, case_title)
            case_title = "{},{}：不符合IPV4格式的数据，{}".format(model_data['用例标题'], data_step, tip)
            self.step_common(model_data, data_step, test_data.test_data('ipv6'), '失败', case_data, case_title)
        elif keyword.upper() == 'IPV6':
            case_title = "{},{}：符合IPV6格式的数据，{}".format(model_data['用例标题'], data_step, tip)
            self.step_common(model_data, data_step, test_data.test_data('ipv6'), '成功', case_data, case_title)
            case_title = "{},{}：不符合IPV6格式的数据，{}".format(model_data['用例标题'], data_step, tip)
            self.step_common(model_data, data_step, test_data.test_data('ipv4'), '失败', case_data, case_title)
        elif keyword.upper() == 'IP':
            case_title = "{},{}：符合IPV4格式的数据，{}".format(model_data['用例标题'], data_step, tip)
            self.step_common(model_data, data_step, test_data.test_data('ipv4'), '成功', case_data, case_title)
            case_title = "{},{}：符合IPV6格式的数据，{}".format(model_data['用例标题'], data_step, tip)
            self.step_common(model_data, data_step, test_data.test_data('ipv6'), '成功', case_data, case_title)
            case_title = "{},{}：不符合IP格式的数据，{}".format(model_data['用例标题'], data_step, tip)
            self.step_common(model_data, data_step, test_data.test_data('数字', 12), '失败', case_data, case_title)
        elif keyword == '域名':
            case_title = "{},{}：符合域名格式的数据，{}".format(model_data['用例标题'], data_step, tip)
            self.step_common(model_data, data_step, test_data.test_data('域名'), '成功', case_data, case_title)
            case_title = "{},{}：不符合域名格式的数据，{}".format(model_data['用例标题'], data_step, tip)
            self.step_common(model_data, data_step, test_data.test_data('字母', 10), '失败', case_data, case_title)
        elif keyword == '端口':
            case_title = "{},{}：端口号小于1，能否{}".format(model_data['用例标题'], data_step, tip)
            self.step_common(model_data, data_step, '0', '失败', case_data, case_title)
            case_title = "{},{}：端口号大于65535，能否{}".format(model_data['用例标题'], data_step, tip)
            self.step_common(model_data, data_step, '65536', '失败', case_data, case_title)
            case_title = "{},{}：端口号等于1，能否{}".format(model_data['用例标题'], data_step, tip)
            self.step_common(model_data, data_step, '1', '成功', case_data, case_title)
            case_title = "{},{}：端口号等于65535，能否{}".format(model_data['用例标题'], data_step, tip)
            self.step_common(model_data, data_step, '65535', '成功', case_data, case_title)

    def generate_case(self, model_data, data_step, need_data, case_data):
        """
        生成用例
        :param model_data:
        :param data_step:
        :param case_data:
        :param need_data:
        :return:
        """
        # TODO 是否必填
        self.required(need_data, model_data, data_step, '', case_data)
        # TODO 根据【必须有的数据类型】生成用例
        if '必须有的数据类型' in need_data.keys():
            must_type = need_data['必须有的数据类型']['value'].split(',')
            self.data_type_case('必须有的数据类型', model_data, must_type, data_step, need_data, '失败', '成功', case_data)
        # TODO 根据【可以有的数据类型】生成用例
        if '可以有的数据类型' in need_data.keys():
            maybe_type = need_data['可以有的数据类型']['value'].split(',')
            if '必须有的数据类型' not in need_data.keys():
                self.data_type_case('可以有的数据类型', model_data, maybe_type, data_step, need_data, '成功', '成功', case_data)
            else:
                self.data_type_case('可以有的数据类型', model_data, maybe_type, data_step, need_data, '失败', '失败', case_data)
                # TODO 必有的数据类型和可以有的数据类型进行组合（必须有的+可以有的其中一个）
                for i in maybe_type:
                    must_type_data = copy.deepcopy(need_data['必须有的数据类型']['value'].split(','))
                    must_type_data.append(i)
                    case_title = "{},{}：包含{}多种数据类型，{}".format(model_data['用例标题'], data_step, must_type_data,
                                                              model_data['结果']['成功'])
                    get_data = test_data.test_data(must_type_data, self.data_len_limit(need_data))
                    self.step_common(model_data, data_step, get_data, '成功', case_data, case_title)
                # TODO 必有的数据类型和可以有的数据类型进行组合（必须有的+可以有的）
                if len(maybe_type) > 1:
                    all_type_data = copy.deepcopy(need_data['必须有的数据类型']['value'].split(',')) + copy.deepcopy(
                        need_data['可以有的数据类型']['value'].split(','))
                    case_title = "{},{}：包含{}多种数据类型，{}".format(model_data['用例标题'], data_step, all_type_data,
                                                              model_data['结果']['成功'])
                    get_data = test_data.test_data(all_type_data, self.data_len_limit(need_data))
                    self.step_common(model_data, data_step, get_data, '成功', case_data, case_title)
        # TODO 根据字符长度生成用例
        if '字符长度' in need_data.keys():
            data_len = need_data['字符长度']['value']
            # TODO 等于最小值
            self.data_len_case(model_data, need_data, data_step, data_len[0], '等于', '成功', case_data)
            # TODO 小于最小值
            self.data_len_case(model_data, need_data, data_step, data_len[0], '小于', '失败', case_data)
            if len(data_len) > 1:
                # TODO 等于最大值
                self.data_len_case(model_data, need_data, data_step, data_len[1], '等于', '成功', case_data)
                # TODO 大于最大值
                self.data_len_case(model_data, need_data, data_step, data_len[1], '大于', '失败', case_data)
            else:
                # TODO 大于
                self.data_len_case(model_data, need_data, data_step, data_len[0], '大于', '失败', case_data)
        # TODO 根据【特殊类型】生成用例
        if '特殊类型' in need_data.keys():
            for i in need_data['特殊类型']['value'].split(','):
                self.data_type_special(model_data, need_data, data_step, i, case_data)

    def case(self):
        return self.operation_type('输入', self.generate_case)


def result():
    return InputOperation().case()


if __name__ == '__main__':
    import json

    ReadXmind(path=r'C:\Users\admin\Desktop\NAVS.xmind', sheet='画布2').processed_data()
    test = result()
    print(json.dumps(test, ensure_ascii=False))
